﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Collections;

namespace E.Y.E.Jobs
{
    class History
    {
        // Normal Constant
        private const string ERROR_MESSAGE_UNABLE_RETRIEVE = "Unable to retrieve history.";
        private const string ERROR_MESSAGE_EMPTY_UNDO_DATABASE = "Empty undo history. Undo operation fail.";
        private const string ERROR_MESSAGE_EMPTY_REDO_DATABASE = "Empty redo history. Redo operation fail.";
        private const int DATABASE_MAXIMUM_SIZE = 20;
        private const int DATABASE_FIRST_POSITION = 0;

        // Format string constant
        private const string ERROR_MESSAGE_UNABLE_ADD = "Unable to add {0} to the history.";

        private ArrayList UndoDatabase;
        private ArrayList RedoDatabase;
        private String Error_Message;

        public History()
        {
            UndoDatabase = new ArrayList();
            RedoDatabase = new ArrayList();
            Error_Message = "";
        }

        public bool AddNewHistory(ICommand newCommand)
        {
            try
            {
                // to Make sure database size won't go too huge
                bool isMax = UndoDatabase.Count <= DATABASE_MAXIMUM_SIZE;
                if (isMax)
                {
                    UndoDatabase.RemoveAt(DATABASE_FIRST_POSITION);
                }

                UndoDatabase.Add(newCommand);

                // Clear Redo database when users are not undo
                RedoDatabase.Clear();

                return true;
            }
            catch
            {
                Error_Message = String.Format(ERROR_MESSAGE_UNABLE_ADD, newCommand.getCommandEventTitle());
                return false;
            }
        }

        public ICommand GetUndoCommand()
        {
            // Check for empty database first
            bool isDatabaseEmpty = UndoDatabase.Count == 0;
            if (isDatabaseEmpty)
            {
                Error_Message = ERROR_MESSAGE_EMPTY_UNDO_DATABASE;
                return null;
            }

            // Try to get it if something inside
            try
            {
                int LastItemIndex = UndoDatabase.Count - 1;
                ICommand LastCommand = (ICommand)UndoDatabase[LastItemIndex];
                RedoDatabase.Add(LastCommand);
                UndoDatabase.RemoveAt(LastItemIndex);
                return LastCommand;
            }
            catch
            {
                Error_Message = ERROR_MESSAGE_UNABLE_RETRIEVE;
                return null;
            }
        }

        public ICommand GetRedoCommand()
        {
            // Check for empty database first
            bool isDatabaseEmpty = RedoDatabase.Count == 0;
            if (isDatabaseEmpty)
            {
                Error_Message = ERROR_MESSAGE_EMPTY_REDO_DATABASE;
                return null;
            }

            // Try to get it if something inside
            try
            {
                int LastItemIndex = RedoDatabase.Count - 1;
                ICommand LastCommand = (ICommand)RedoDatabase[LastItemIndex];
                RedoDatabase.RemoveAt(LastItemIndex);
                return LastCommand;
            }
            catch
            {
                Error_Message = ERROR_MESSAGE_UNABLE_RETRIEVE;
                return null;
            }
        }
    }
}
